package com.easymin.weixin.controller.res;


import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.common.DataGrid;
import com.easymin.weixin.common.api.DaijiaApi;
import com.easymin.weixin.controller.v4.ResultTransport;
import com.easymin.weixin.entity.WxApplication;
import com.easymin.weixin.entity.zhuanche.Order;
import com.easymin.weixin.manager.WxApplicationManager;
import com.easymin.weixin.manager.ZhuancheManager;

@RestController
@RequestMapping("api/zhuanche")
public class ZhuanOrderRes {
  
  private static final Logger logger = LoggerFactory.getLogger(ZhuanOrderRes.class);
  
  @Autowired
  private ZhuancheManager zhuancheManager;
  @Autowired
  private WxApplicationManager wxApplicationManager;
  @Autowired
  private DaijiaApi daijiaApi;

  /**
   * 创建专车订单.
   */
  @RequestMapping(value = {"create"}, method = RequestMethod.POST)
  public @ResponseBody Map<String, Object> createOrder(
      @RequestParam("passengerId") Long passengerId,
      @RequestParam("passengerName") String passengerName,
      @RequestParam("passengerPhone") String passengerPhone,
      @RequestParam("showPhone") String showPhone,
      @RequestParam("companyId") Long companyId,
      @RequestParam("companyName") String companyName,
      @RequestParam("carTypeId") Long carTypeId,
      @RequestParam("channelName") String channelName,
      @RequestParam("startAddress") String startAddress, 
      @RequestParam(required = false, value = "startAddressDetail") String startAddressDetail,
      @RequestParam("startLat") Double startLat,
      @RequestParam("startLng") Double startLng,
      @RequestParam(required = false, value = "endAddress") String endAddress, 
      @RequestParam(required = false, value = "endAddressDetail") String endAddressDetail,
      @RequestParam(required = false, value = "endLat") Double endLat, 
      @RequestParam(required = false, value = "endLng") Double endLng,
      @RequestParam(required = false, value = "serverTime") Long serverTime,
      @RequestParam(required = false, value = "budgetPay") Double budgetPay,
      @RequestParam(required = false, value = "preStartPrice") Double preStartPrice, 
      @RequestParam(required = false, value = "preMileagePrice") Double preMileagePrice, 
      @RequestParam(required = false, value = "preRunTimePrice") Double preRunTimePrice, 
      @RequestParam(required = false, value = "preTravelTime") Integer preTravelTime, 
      @RequestParam(required = false, value = "preMileage") Double preMileage, 
      @RequestParam(required = false, value = "couponId") Long couponId, 
      @RequestParam("appKey") String appKey) throws ParseException {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      String string = daijiaApi.findErrandSetting(wxApplication.getAddress());
      JSONObject jsonObject = JSON.parseObject(string);
      Boolean zhuanchePrePay = jsonObject.getBooleanValue("zhuanchePrePay");
      map =
          zhuancheManager.createOrder(passengerId, passengerName, passengerPhone, showPhone,
              companyId, companyName, carTypeId, channelName, startAddress, startAddressDetail,
              startLat, startLng, endAddress, endAddressDetail, endLat, endLng, serverTime,
              couponId, budgetPay, preStartPrice, preMileagePrice, preRunTimePrice, preTravelTime,
              preMileage, zhuanchePrePay, appKey, wxApplication.getAddress());

    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", ex.getMessage());
    }
    return map;
  }

  /**
   * 查询单个订单.
   */
  @RequestMapping(value = {"findOne"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> findOne(
      @RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    appKey = StringUtils.trimToEmpty(appKey);
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);

    try {
      Map<String, Object> data = new HashMap<String, Object>();
      data = zhuancheManager.findOrder(wxApplication.getAddress(), orderId, appKey);

      map.put("code", 0);
      map.put("msg", "成功");
      map.put("data", data);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "加载数据失败");
      return map;
    }
  }

  /**
   * 查询客户当前订单.
   */
  @RequestMapping(value = {"findOrders"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> findOrders(
      @RequestParam("passengerId") Long passengerId,
      @RequestParam("page") Integer page,
      @RequestParam("rows") Integer rows,
      @RequestParam(required = false, value = "status") String status,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    appKey = StringUtils.trimToEmpty(appKey);
    try {
      DataGrid<Map<String, Object>> list = new DataGrid<Map<String, Object>>();
      list = zhuancheManager.findByParam(passengerId, page, rows, status, appKey);
      map.put("code", 0);
      map.put("msg", "成功");
      map.put("data", list);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "加载数据失败");
      return map;
    }
  }

  /**
   * 查询附近服务人员.
   */
  @RequestMapping(value = {"queryNearDriver"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> queryNearDriver(
      @RequestParam("longitude") Double longitude, 
      @RequestParam("latitude") Double latitude,
      @RequestParam("carTypeId") Long carTypeId, 
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.queryNearDriver(wxApplication.getAddress(), longitude, latitude, carTypeId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "查询附近服务人员失败");
      return map;
    }
  }

  /**
   * 获取预估价钱.
   */
  @RequestMapping(value = {"getPrice"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> getPrice(
      @RequestParam("areaId") Long areaId,
      @RequestParam("startLat") Double startLat,
      @RequestParam("startLng") Double startLng,
      @RequestParam("endLat") Double endLat,
      @RequestParam("endLng") Double endLng,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    if (areaId == null || areaId == 0) {
      map.put("code", -1);
      map.put("msg", "收费信息为空");
      return map;
    }
    if (startLat == null || startLat == 0 || startLng == null || startLng == 0) {
      map.put("code", -2);
      map.put("msg", "预约地位置不能为空");
      return map;
    }
    if (endLat == null || endLat == 0 || endLng == null || endLng == 0) {
      map.put("code", -3);
      map.put("msg", "目的地位置不能为空");
      return map;
    }
    try {
      Map<String, Object> map2 =
          daijiaApi.getZhuanchePrice(wxApplication.getAddress(), areaId, startLat, startLng,
              endLat, endLng);
      if (map2.get("success").equals(true)) {
        map.put("code", 0);
        map.put("msg", "成功");
        map.put("data", map2);
      } else {
        map.put("code", -4);
        map.put("msg", map2.get("message"));
      }
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "预算价格失败");
      return map;
    }
  }

  /**
   * 获取预估价钱.
   */
  @RequestMapping(value = {"getNewPrice"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> getNewPrice(
      @RequestParam("areaId") Long areaId,
      @RequestParam(required = false, value = "time") Integer time, 
      @RequestParam(required = false, value = "mileage") Double mileage,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    if (areaId == null || areaId == 0) {
      map.put("code", -1);
      map.put("msg", "收费信息为空");
      return map;
    }
    try {
      Map<String, Object> map2 =
          daijiaApi.getZhuancheNewPrice(wxApplication.getAddress(), areaId, time, mileage);
      if (map2.get("success").equals(true)) {
        map.put("code", 0);
        map.put("msg", "成功");
        map.put("data", map2);
      } else {
        map.put("code", -4);
        map.put("msg", map2.get("message"));
      }
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "预算价格失败");
      return map;
    }
  }

  /**
   * 支付宝支付接口.
   */
  @RequestMapping(value = {"aliprepay"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> aliprepay(
      @RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.zhuanchealiPrepay(wxApplication.getAddress(), orderId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "支付接口失败w");
      return map;
    }
  }

  /**
   * 微信支付接口.
   */
  @RequestMapping(value = {"wxprepay"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> wxprepay(
      @RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.zhuanchewxPrepay(wxApplication.getAddress(), orderId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "调用支付接口失败");
      return map;
    }
  }

  /**
   * 专车的余额签单预支付.
   */
  @RequestMapping(value = {"balanceSignPay"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> balanceSignPay(
      @RequestParam("orderId") Long orderId,
      @RequestParam("passengerId") Long passengerId,
      @RequestParam("payType") String payType, //签单:sign, 余额:balance
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map =
          daijiaApi.balanceSignPayZhuan(wxApplication.getAddress(), orderId, passengerId, payType);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "内部服务器失败");
      return map;
    }
  }

  /**
   * 改变订单状态.
   * @param orderId 订单Id
   * @param employId 服务人员Id
   * @param action 销单:cancel 接单:jiedan 开始等待:wait 执行:run 拒接:refuse
   * @param operator 操作人
   * @param cause 销单原因
   */
  @ResponseBody
  @RequestMapping(value = {"update"}, method = RequestMethod.POST)
  public Map<String, Object> update(
      @RequestParam("orderId") Long orderId,
      @RequestParam(required = false, value = "employId") Long employId,
      @RequestParam("action") String action, 
      @RequestParam("operator") String operator,
      @RequestParam(required = false, value = "cause") String cause,
      @RequestParam("appKey") String appKey) {
    appKey = StringUtils.trimToEmpty(appKey);
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      if ("jiedan".equals(action)) {
        Map<String, Object> map2 = daijiaApi.queryDriver(wxApplication.getAddress(), employId);
        Boolean success = (Boolean) map2.get("success");
        if (success) {
          String employName = (String) map2.get("employName");
          String employPhone = (String) map2.get("employPhone");
          String employNo = (String) map2.get("employNo");
          Long employCompanyId = (Long) map2.get("employCompanyId");
          String employPhoto = (String) map2.get("employPhoto");
          Double employScore = (Double) map2.get("employScore");
          map =
              zhuancheManager.update(wxApplication.getAddress(), orderId, employId, employName,
                  employPhone, employCompanyId, employNo, employPhoto, employScore, action,
                  operator, cause, appKey);
        } else {
          map.put("code", -1);
          map.put("msg", map2.get("message"));
        }
      } else {
        map =
            zhuancheManager.update(wxApplication.getAddress(), orderId, employId, null, null, null,
                null, null, null, action, operator, cause, appKey);
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "内部服务器错误");
    }
    return map;
  }

  /**
   * 评价订单.
   */
  @RequestMapping(value = {"review"}, method = RequestMethod.POST)
  public @ResponseBody Map<String, Object> review(@RequestParam("orderId") Long orderId,
      @RequestParam("score") Double score,
      @RequestParam(required = false, value = "content") String content,
      @RequestParam("appKey") String appKey) {
    appKey = StringUtils.trimToEmpty(appKey);
    Map<String, Object> map = new HashMap<String, Object>();
    try {
      String review = zhuancheManager.review(orderId, score, content, appKey);

      if (StringUtils.isBlank(review)) {
        map.put("code", 0);
        map.put("msg", "成功");
        map.put("data", null);
      } else {
        map.put("code", -1);
        map.put("msg", review);
      }

    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "内部服务器错误");
    }
    return map;
  }

  /**
   * 催一下专车订单进度.
   * @param orderId 订单Id
   */
  @RequestMapping(value = {"reminder"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> reminder(@RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) throws Exception {
    Map<String, Object> map = new HashMap<String, Object>();

    appKey = StringUtils.trimToEmpty(appKey);
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Order order = zhuancheManager.findOne(orderId, appKey);
    if (null == order) {
      map.put("code", -1);
      map.put("msg", "订单不存在");
      return map;
    }
    if (order.getStatus() == 5 || order.getStatus() == 6) {
      map.put("code", -2);
      map.put("msg", "订单已完成,或已销单,催促无效");
      return map;
    }
    if (order.getLasturge() != null) {
      if ((new Date().getTime() - order.getLasturge().getTime()) < (2 * 60 * 1000)) { // 小于两分钟
        map.put("code", -1);
        map.put("msg", "订单刚催促过,两分钟内不能重复操作");
        return map;
      }
    }

    try {

      String content = zhuancheManager.hasten(orderId, appKey); // 调用专车系统更新上次催促时间
      if ("success".equals(content)) {
        daijiaApi.hastenZhuanOrder(wxApplication.getAddress(), orderId); // 调用代驾的接口让其显示专车催单消息
        map.put("code", 0);
        map.put("msg", "消息已发出,管理员已经知道了");
        if (order.getLasturge() != null) {
          if (order.getCreated().getTime() == order.getLasturge().getTime()) {
            map.put("msg", "我们正在为您安排服务人员");
          }
        }
        map.put("data", null);
      } else if ("fail".equals(content)) {
        map.put("code", -1);
        map.put("msg", "催单失败");
      }
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "催促操作失败");
      return map;
    }
  }

  /**
   * 专车单结算页面的数据.
   */
  @RequestMapping(value = {"completeTask"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> completeTask(
      @RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.completeTaskZhuan(wxApplication.getAddress(), orderId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "获取专车结算页面的数据失败");
      return map;
    }
  }

  /**
   * 确认专车订单费用的接口.
   * @param orderId 订单id
   * @param realCash 实付金额
   * @param guoluMoney 过路费
   * @param yuanchengMoney 远程费
   * @param otherMoney 其他费
   * @param mileage 里程
   * @param waitedTime 等待时间
   * @param travelTime 行驶时间
   * @param toPlace 实际目的地
   * @param toPlaceLng 目的地详情经度
   * @param toPlaceLat 目的地详情纬度
   * @param xml 保单数据
   */
  @ResponseBody
  @RequestMapping(value = {"confirmTask"}, method = RequestMethod.POST)
  public Map<String, Object> confirmTask(
      @RequestParam("orderId") Long orderId,
      @RequestParam("realCash") Double realCash,
      @RequestParam("guoluMoney") Double guoluMoney,
      @RequestParam("yuanchengMoney") Double yuanchengMoney,
      @RequestParam("otherMoney") Double otherMoney,
      @RequestParam("mileage") Double mileage,
      @RequestParam("waitedTime") Integer waitedTime,
      @RequestParam("travelTime") Integer travelTime,
      @RequestParam("xml") String xml,
      @RequestParam(required = false, value = "toPlace") String toPlace, 
      @RequestParam(required = false, value = "toPlaceLng") Double toPlaceLng,
      @RequestParam(required = false, value = "toPlaceLat") Double toPlaceLat,
      @RequestParam("startPrice") Double startPrice,
      @RequestParam("mileagePrice") Double mileagePrice,
      @RequestParam("runTimePrice") Double runTimePrice,
      @RequestParam(required = false, value = "waitPrice") Double waitPrice,
      @RequestParam(required = false, value = "memo") String memo,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      Order order = zhuancheManager.findOne(orderId, appKey);
      if (order.getStatus() == 6) {
        map.put("code", -2);
        map.put("msg", "订单已经取消");
        return map;
      }
      map =
          daijiaApi.confirmTaskZhuan(wxApplication.getAddress(), orderId, realCash, guoluMoney,
              yuanchengMoney, otherMoney, mileage, waitedTime, travelTime, xml, toPlace,
              toPlaceLng, toPlaceLat, startPrice, mileagePrice, runTimePrice, waitPrice, memo);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "确认订单费用失败");
      return map;
    }
  }

  /**
   * 实时获取订单是否被结算.
   */
  @ResponseBody
  @RequestMapping(value = {"checkTask"}, method = RequestMethod.GET)
  public  Map<String, Object> checkTask(@RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.checkTaskZhuan(wxApplication.getAddress(), orderId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "实时获取订单是否被结算失败!");
      return map;
    }
  }

  /**
   * 最后结算接口.
   * @param payType 支付类型: helppay(代付) sign(签单) balance(余额)
   */
  @RequestMapping(value = {"finishTask"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> finishTask(
      @RequestParam("orderId") Long orderId,
      @RequestParam("payType") String payType,
      @RequestParam(required = false, value = "who") String who,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.finishTaskZhuan(wxApplication.getAddress(), orderId, payType, who);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "结算提交失败!");
      return map;
    }
  }

  /**
   * 专车订单客户端支付所需数据.
   */
  @RequestMapping(value = {"clientPayData"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> clientPayData(
      @RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.clientPayDataZhuan(wxApplication.getAddress(), orderId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "获取专车结算页面的数据失败");
      return map;
    }
  }

  /**
   * 客户端支付宝结算专车订单.
   */
  @RequestMapping(value = {"aliAfterPay"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> aliAfterpay(
      @RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.aliAfterpayZhuan(wxApplication.getAddress(), orderId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "获取结算页面的数据失败");
      return map;
    }
  }

  /**
   * 客户端微信结算专车订单.
   */
  @RequestMapping(value = {"wxAfterPay"}, method = RequestMethod.GET)
  public @ResponseBody Map<String, Object> wxAfterpay(@RequestParam("orderId") Long orderId,
      @RequestParam("appKey") String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    try {
      map = daijiaApi.wxAfterpayZhuan(wxApplication.getAddress(), orderId);
      return map;
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      map.put("code", 500);
      map.put("msg", "获取结算页面的数据失败");
      return map;
    }
  }

  /**
   * 客户端销单.
   */
  @RequestMapping(value = {"cancel"}, method = RequestMethod.POST)
  public ResultTransport cancel(
      @RequestParam("orderId") Long orderId,
      @RequestParam("cause") String cause,
      @RequestParam("appKey") String appKey) {
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    ResultTransport transport = daijiaApi.cancelZhuancheOrderCustomer(
            wxApplication.getAddress(), orderId, cause);// 司机销单推送给客户,并退款

    return transport;
  }

}
